package thread;

import java.util.LinkedList;
import java.util.Objects;

import thread.concurrence.ConcurrentTicket;
import thread.synchronize.SynchronizedTicket;

/**
 * Customer类的实例充当了购买票的顾客角色
 * @author fidel
 */
public class Customer {
    private String name;
    private LinkedList<Ticket> tickets = new LinkedList<>();
    /** 此属性值在被修改后，对其他线程立即可见 */
    private volatile boolean knowNoTicketForPurchase = false;
    
    public LinkedList<Ticket> buyTicket(Class<? extends Ticket> ticketClass) {
        // 如果不知道没有票供购买
        if (!knowNoTicketForPurchase) {
            new Thread() {
                @Override
                public void run() {
                    Ticket ticket = null;
                    if (ticketClass.equals(SynchronizedTicket.class)) {
                        ticket = SynchronizedTicket.sellOne(getOneself());
                    } else if (ticketClass.equals(ConcurrentTicket.class)) {
                        ticket = ConcurrentTicket.sellOne(getOneself());
                    } else {
                        throw new RuntimeException("Ticket类不符合要求");
                    }
                    if (Objects.nonNull(ticket)) {
                        tickets.add(ticket);
                        System.out.println("顾客" + getOneself().getName() + "此时已购买" + tickets.size() + "张票");
                    } else {
                        if (!knowNoTicketForPurchase) {
                            // 更改此属性的值，刷新此属性在其他线程中缓存的值
                            knowNoTicketForPurchase = true;
                            System.out.println("顾客" + getOneself().getName() + "在购票时，被告知票已售罄");
                        }
                    }
                }
            }.start();
        }
        return tickets;
    }

    public String getName() {
        return name;
    }

    public Customer getOneself() {
        return this;
    }

    public Customer(String name) {
        this.name = name;
    }
}
